package cn.rkylin.oms.warehouse.stock.service;

import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.rkylin.oms.common.base.AbstractAdapterFactory;
import cn.rkylin.oms.common.dto.DBLog;
import cn.rkylin.oms.common.utils.CodeUtil;
import cn.rkylin.oms.common.utils.DateUtil;
import cn.rkylin.oms.common.utils.LogUtil;
import cn.rkylin.oms.goods.domain.GoodsSku;
import cn.rkylin.oms.goods.service.IGoodsService;
import cn.rkylin.oms.system.project.vo.ProjectVO;
import cn.rkylin.oms.system.storage.domain.Stor;
import cn.rkylin.oms.system.storage.service.IStorService;
import cn.rkylin.oms.warehouse.stock.dao.IStockDAO;
import cn.rkylin.oms.warehouse.stock.domain.Stock;
import cn.rkylin.oms.warehouse.stock.domain.StockBalance;
import cn.rkylin.oms.warehouse.stockdiff.dao.IStockDiffDAO;
import cn.rkylin.oms.warehouse.stockdiff.domain.StockDiff;

/**
 * 库存服务实现类
 *
 * @author liming
 * @date 2017/10/30
 */
@Service("stockService")
public class StockServiceImpl implements IStockService {

    private static final String CC = "cc";  // 库存类型：残次
    private static final String ZP = "zp";  // 库存类型：正品

    @Autowired
    private IStockDAO stockDAO;

    @Autowired
    private IStockDiffDAO stockDiffDAO;

    @Autowired
    private IStorService storService;

    @Autowired
    private LogUtil logUtil;

    @Autowired
    private IGoodsService goodsService;

    /**
     * 项目库存结余
     *
     * @param prjId
     * @return
     */
    @Override
    public int insertStockBalance(String prjId) throws Exception {

        // 获取项目所有仓库
        List<Stor> storList = storService.findByProjectId(prjId);
        if (storList.isEmpty()) {
            logUtil.info(new DBLog(prjId, "库存结余", "", "项目无仓库，执行完成"));
            return 1;
        }

        // 逐个仓库结余
        for (Stor stor : storList) {
            // 获取库存
            List<Stock> stockList = getStockListByStorId(stor.getStorId());
            if (stockList.isEmpty()) {
                continue;
            }

            // 插入到库存结余表
            for (Stock stock : stockList) {
                StockBalance stockBalance = new StockBalance();
                stockBalance.setBalanceId(UUID.randomUUID().toString().replaceAll("-", ""));
                stockBalance.setBalanceDate(DateUtil.getCurrentDateStr("yyyy-MM-dd"));
                BeanUtils.copyProperties(stock, stockBalance);
                try {

                    // 成本价
                    GoodsSku sku = goodsService.getGoodsSkuBySkuId(stock.getSkuId());
                    if (sku == null) {
                        stockBalance.setCostPrice(new BigDecimal(0));
                    } else {
                        stockBalance.setCostPrice(sku.getCostPrice());
                    }

                    stockDAO.insertStockBalance(stockBalance);
                } catch (Exception ex) {
                    logUtil.error(new DBLog(stockBalance.getBalanceId(), "库存结余", "", "库存结余失败:" + ex.getCause().getMessage()));
                }
            }
            logUtil.info(new DBLog(stor.getStorName(), "库存结余", stor.getStorName(), "仓库结余执行完成"));
        }

        logUtil.info(new DBLog(prjId, "库存结余", "", "项目结余执行完成"));
        return 1;
    }

    /**
     * 获取仓库库存
     * 
     * @param storId
     * @return
     * @throws Exception
     */
    private List<Stock> getStockListByStorId(String storId) throws Exception {
        Stock param = new Stock();
        param.setStorId(storId);
        return stockDAO.findByWhere(param);
    }
    
    /**
     * 获取库存结余
     * 
     * @param storId
     * @return
     * @throws Exception
     */
    private List<StockBalance> getStockBalanceListByStorId(String storId) throws Exception {
        return stockDAO.findStockBalanceByWhere(storId);
    }

    @Override
    public int insertStockDiff(String prjId) throws Exception {
        ProjectVO project = AbstractAdapterFactory.getProject(prjId);
        // 获取项目所有仓库
        List<Stor> storList = storService.findByProjectId(prjId);
        if (storList.isEmpty()) {
            logUtil.info(new DBLog(prjId, "库存差异", "", "项目无仓库，执行完成"));
            return 1;
        }

        String storkDiffCode = generateReturnCodeWithType("SD", project);
        // 逐个仓库比对差异
        for (Stor stor : storList) {
            // 获取库存
            List<StockBalance> stockList = getStockBalanceListByStorId(stor.getStorId());
            if (stockList.isEmpty()) {
                continue;
            }

            // 插入到库存差异表
            for (StockBalance stock : stockList) {
                // 循环库存
                StockDiff stockDiff = new StockDiff();
                
                stockDiff.setPrjId(prjId);
                stockDiff.setEntId(project.getEntId());
                stockDiff.setStorId(stock.getStorId());
                stockDiff.setStorCode(stock.getStorCode());
                stockDiff.setStorName(stock.getStorName());
                stockDiff.setDiffCode(storkDiffCode);

                BeanUtils.copyProperties(stock, stockDiff);

                // 正品差异(本地计算库存数与第三方库存数对比)
                if(stock.getStockQty().intValue()!=stock.getSellCount().intValue()) {
                    stockDiff.setInventoryType(ZP);
                    stockDiff.setStockQty(stock.getStockQty());
                    stockDiff.setSellCount(stock.getSellCount());
                    try {
                        stockDiffDAO.insertStockDiff(stockDiff);
                    } catch (Exception e) {
                        logUtil.error(new DBLog(stor.getStorName(), "库存差异", stor.getStorName(), "仓库["+stock.getStorName()+"]中商品["+stock.getSkuCode()+"]存在正品库存差异，但生成失败"));
                    }
                }
                // 次品差异
                if(stock.getJunkQty().intValue()!=stock.getJunkCount().intValue()) {
                    stockDiff.setInventoryType(CC);
                    stockDiff.setStockQty(stock.getJunkQty());
                    stockDiff.setSellCount(stock.getJunkCount());
                    try {
                        stockDiffDAO.insertStockDiff(stockDiff);
                    } catch (Exception e) {
                        logUtil.error(new DBLog(stor.getStorName(), "库存差异", stor.getStorName(), "仓库["+stock.getStorName()+"]中商品["+stock.getSkuCode()+"]存在残次品库存差异，但生成失败"));
                    }
                }
            }
            logUtil.info(new DBLog(stor.getStorName(), "库存差异", stor.getStorName(), "仓库["+stor.getStorName()+"]的库存差异生成完毕"));
        }

        logUtil.info(new DBLog(prjId, "库存差异", "", "项目["+project.getPrjName()+"]库存差异执行完成"));
        return 1;
    }

    /**
     * generateReturnCodeWithType:编码生成方法 <br/>
     *
     * @author zhanghao
     * @param codeType
     *            编码类型
     * @param shopId
     *            店铺ID
     * @return
     * @throws Exception
     */
    private String generateReturnCodeWithType(String codeType, ProjectVO project) throws Exception {
        String prjShortName = project.getPrjShortName();
        String returnCode = codeType + prjShortName + CodeUtil.getCode();
        return returnCode;
    }
}
